import uuid
from handlers import BaseHandler
from model import User, Group
from tornado.gen import coroutine
from forms import CreateUserForm, LoginForm
from utils.multithreading import executor
from tornado.stack_context import wrap


class LoginHandler(BaseHandler):
    @coroutine
    def post(self):
        form = LoginForm(self.request.arguments)
        if form.validate():
            query = self.session.query(User).filter_by(username=form.data["username"])
            user = yield executor(wrap(query.first))
            if user is None:
                self.finish({"status": True, "response": "not find User"})
                return
            if user.check_password_is_correct(form.data["password"]):
                hex = uuid.uuid4().hex
                self.redis.set(hex, user.to_dict())
                self.finish({"status": True, "response": hex})
            else:
                self.finish({"status": False, "response": "check password error"})
        else:
            self.finish({"status": False, "response": form.errors})


class UserHandler(BaseHandler):
    @coroutine
    def get(self):
        query = self.session.query(User)
        users = yield executor(query.all)
        response = []
        for user in users:
            response.append(user.to_dict())
        self.finish({"status": True, "response": response})

    @coroutine
    def post(self):
        form = CreateUserForm(self.request.arguments)
        if form.validate():
            data = form.data
            user = User(**data)
            query = self.session.query(User).filter_by(username=user.username)
            first_user = yield executor(query.first)
            if first_user is None:
                user.encrypt_password()
                yield executor(wrap(self.session.commit))
                self.finish({"status": True, 'response': user.to_dict()})
            else:
                self.finish({"status": False, 'response': "User already exists"})
        else:
            self.finish({"status": False, 'response': form.errors})

    @coroutine
    def delete(self):
        id = self.get_argument("id")
        query = self.session.query(User).filter_by(id=id)
        user = yield executor(query.first)
        self.session.delete(user)
        yield executor(wrap(self.session.commit), *())
        self.finish({"status": True, 'response': user.to_dict()})
